// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_FILE_ACFILE_HPP_
#define LIBV_FILE_ACFILE_HPP_

#include <assert.h>
#include <string>
#include <libv/stdint.h>
#include <libv/acfile.h>



namespace libv
{

bool ACFile::Open(const ::std::string& file_path,
                  const int open_type,
                  const bool enable_read_ahead_caching /*= true*/) const
{
    return OpenImpl(file_path, open_type, enable_read_ahead_caching, true);
}



bool ACFile::Open(const ::std::string& file_path,
                  const int open_type,
                  const bool enable_read_ahead_caching /*= true*/)
{
    return OpenImpl(file_path, open_type, enable_read_ahead_caching, false);
}



bool ACFile::Write(const fpos64& offset,
                   const void* data,
                   const uint32_t data_size,
                   ACFile::RequestCompletionHandle* completion_handle)
{
    if ( !is_opened() || read_only() )
    {
        last_error_ = LIBV_FILE_ERROR_INVALID_HANDLE;
        return false;
    }

    if ( offset < 0 ||
         data == NULL || data_size == 0 ||
         completion_handle == NULL )
    {
        last_error_ = LIBV_FILE_ERROR_BAD_ARGUMENTS;
        return false;
    }


    // Преаллокация выполняется синхронно.
    // Однако если не выполнить ее "вручную", система все равно сделает это
    // и тогда весь вызов Write будет синхронным. А так только преаллокация.
    // А в линуксе асинхронный aio_write похоже вообще не пишет за конец файла.
    if ( !PreallocateAtLeast(offset + data_size) )
        return false;

    return WriteImpl(offset, data, data_size, completion_handle);
}



bool ACFile::Read(const fpos64& offset,
                  volatile void* buffer,
                  const uint32_t buffer_size,
                  ACFile::RequestCompletionHandle* completion_handle) const
{
    if ( !is_opened() )
    {
        last_error_ = LIBV_FILE_ERROR_INVALID_HANDLE;
        return false;
    }

    if ( offset < 0 || buffer == NULL ||
         offset + buffer_size > Size() || buffer_size == 0 ||
         completion_handle == NULL )
    {
        last_error_ = LIBV_FILE_ERROR_BAD_ARGUMENTS;
        return false;
    }

    return ReadImpl(offset, buffer, buffer_size, completion_handle);
}

}  // libv

#endif  // LIBV_FILE_ACFILE_HPP_

